package com.demo.thread.demo_thread_create_way;

import cn.hutool.core.collection.CollectionUtil;
import org.springframework.util.CollectionUtils;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Future.get的行为取决于任务的状态.如果任务已经完成,那么get会立即返回结果,否则get将阻塞直到任务进入完成状态,然后返回结果或者抛出异常
 * Future 一旦计算完成，就不能再重新开始
 * @author peter
 * @date 2022/3/4 23:54
 */
public class Demo3 implements Callable<String> {

    public static AtomicInteger count = new AtomicInteger(20);

    @Override
    public String call() throws Exception {
        System.out.println("外层逻辑" + Thread.currentThread().getName()+"当前票数：" + count);

        while (count.get() > 0) {
            int i = count.getAndDecrement();
            if (i > 0) {
                System.out.println(Thread.currentThread().getName()+"-当前剩余票数:"+i);
            }
        }

        return "sale out";
    }

    public static void main(String[] args) {
        try {
            Callable<String> demo3 = new Demo3();
            FutureTask<String> objectFutureTask = new FutureTask<>(demo3);
            FutureTask<String> objectFutureTask2 = new FutureTask<>(demo3);
            FutureTask<String> objectFutureTask3 = new FutureTask<>(demo3);

            Thread thread1 = new Thread(objectFutureTask, "线程1");
            Thread thread2 = new Thread(objectFutureTask, "线程2");
            Thread thread3 = new Thread(objectFutureTask, "线程3");

            ExecutorService executorService = Executors.newFixedThreadPool(3);

            // 多线程测试
            executorService.submit(thread1);
            executorService.submit(thread2);// 不会执行，objectFutureTask一旦计算完成，就不能再重新开始
            executorService.submit(thread3);// 不会执行，objectFutureTask一旦计算完成，就不能再重新开始或取消计算.

            // Future.get的行为取决于任务的状态.如果任务已经完成,那么get会立即返回结果,否则get将阻塞直到任务进入完成状态,然后返回结果或者抛出异常
            System.out.println("阻塞当前线程");
            // 阻塞当前线程，知道get返回结果
            System.out.println(objectFutureTask.get());
            // get到结果，任务执行完毕
            System.out.println("当前线程已获得计算结果");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
